-
Notifications
You must be signed in to change notification settings - Fork 46
Update time management of python test generation #1893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
return@breaking | ||
} | ||
|
||
algo.run(hintCollector.result, isCancelled, annotationHandler) | ||
algo.run(hintCollector.result, typeInferenceCancellation, annotationHandler) | ||
|
||
val existsAnnotation = method.definition.type | ||
if (existsAnnotation.arguments.all { it.pythonTypeName() != "typing.Any" }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this is wrong. Example:
def f(x: list): pass
In this case we need type inference for intermal type.
We can get information about whether function signature has Any's inside type inference algorithm. In that case initial state has no Any nodes, and the main loop makes only one iteration (initial state -> no new states -> finish).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem with setting limitManager.mode = TimeoutMode
.
Fixed |
if (existsAnnotation.arguments.all { it.pythonTypeName() != "typing.Any" }) { | ||
if (iterationNumber == 1) { | ||
limitManager.mode = TimeoutMode | ||
val existsAnnotation = method.definition.type | ||
annotationHandler(existsAnnotation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially this code was needed to run fuzzing with initial types (even when those are not full). Will we run fuzzing with list[Any]
for the following function?
def f(x: list): ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. But only if all arguments have not-typing.Any
annotations. And if all annotations are full we run fuzzing twice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure? Type inference does not run annotationHandler on initial signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I run fuzzing with initial annotations only after type inference) But I can change program and run fuzzing twice with initial annotations, but I think it isn't a good solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added handling of an initial annotation after first expansion in BaselineAlgorithm.
- if annotation is full we cannot expand it and stop type inference and then start fuzzing;
- if annotation is not full we try to expand and first of all try to fuzz initial annotation (for example, if it is
list[typing.Any]
we can generate empty list), after that we continue type inference
@@ -195,7 +197,6 @@ class PythonEngine( | |||
|
|||
is PythonEvaluationSuccess -> { | |||
val coveredInstructions = evaluationResult.coverage.coveredInstructions | |||
coveredInstructions.forEach { coveredLines.add(it.lineNumber) } | |||
|
|||
val summary = arguments | |||
.zip(methodUnderTest.arguments) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On line 215 (sorry, that I comment another line, because I was not able to find how to comment 215) there's no check that:
is ValidExecution -> {
val trieNode: Trie.Node<Instruction> = description.tracer.add(coveredInstructions)
Returns the node the was already found. You can check trieNode.count > 1
to ignore duplicates and minimise the count of tests for user. At the moment similar tests are generated with different arguments, but same trace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Description
New test generation strategy is:
TypeError
orAttributeError
; or we cannot generate any valid representative of the inferred type)In future we can modify strategies and add it to UI. For example, wait max coverage.
Fixes #1874
Fixes #1831
How to test
Manual tests
Fully annotated function
For example,
Expected: two tests (valid and with
ZeroDivisionError
), test generation process lasted all time from UI-settingsOr,
Expected: all time generation, one test with
x = 'ba'
or longer (with timeout 60s) and all covered branches with timeout 180sWithout or partially annotated function
For example,
Expected: all time generation, one test with
x = 'b'
, no one with'ba'
and longer (regardless of timeout)Self-check list
Check off the item if the statement is true. Hint: [x] is a marked item.
Please do not delete the list or its items.